// @author A0096579E

package rightnow.storage;

import java.io.IOException;
import java.util.List;

import org.joda.time.DateTime;

import com.eaio.uuid.UUID;

/**
 * Storage holds data structures used to store or represent Tasks. It performs
 * CRUD(Create, Read, Update, Delete) operations on these data structures. In
 * addtion, Storage also supports undo/redo the CRUD operations as well as the 
 * saving/loading of persistent data.
 */
public interface Storage {
	
	/**
	 * Returns task ID of added task.
	 * @param task - The Task to be added into Storage
	 * @return A unique task ID
	 */
	public UUID addTask(Task task);
	
	/**
	 * Removes Task specified by taskId from Storage if present.
	 * @param taskId - task ID of Task to be removed
	 */
	public void deleteTask(UUID taskId);
	
	/**
	 * Updates Task specified by taskId with attributes of task.
	 * @param taskId - task ID of Task to be edited
	 * @param task - Task with edited attributes
	 */
	public void editTask(UUID taskId, Task task);
	
	/**
	 * Set Task specified by taskId in Storage as pinned.
	 * @param taskId - task ID of Task to be pinned
	 */
	public void pinTask(UUID taskId);
	
	/**
	 * Set Task specified by taskId in Storage as unpinned.
	 * @param taskId - task ID of Task to be unpinned
	 */
	public void unpinTask(UUID taskId);
	
	/**
	 * Set Task specified by taskId in Storage as done.
	 * @param taskId - task ID of Task to be done
	 */
	public void doneTask(UUID taskId);
	
	/**
	 * Set Task specified by taskId in Storage as undone.
	 * @param taskId - task ID of Task to be done
	 */
	public void undoneTask(UUID taskId);
	
	/**
	 * Removes all done Tasks from Storage.
	 */
	public void deleteDoneTasks();
	
	/**
	 * Returns all Tasks in Storage in the form of a List.
	 * @return A list of all Tasks in Storage
	 */
	public List<Task> allTasksToList();
	
	/**
	 * Returns Tasks matching searchTerms in Storage in the form of a List.
	 * @param searchTerms - String of search terms delimited by white space
	 * @return A list of Tasks matching searchTerms
	 */
	public List<Task> matchedTasksToList(String searchTerms);
	
	/**
	 * Returns Tasks coinciding specified dateTime in Storage in the form of a List.
	 * @param dateTime - DateTime used to determine coinciding Tasks
	 * @return A list of Tasks coinciding with dateTime
	 */
	public List<Task> nowTasksToList(DateTime dateTime);
	
	/**
	 * Loads data into Storage from save.xml.
	 * @throws IOException - On failure to load
	 */
	public void loadFile() throws IOException;
	
	/**
	 * Writes data in Storage to save.xml.
	 * @throws IOException - On failure to save
	 */
	public void saveFile() throws IOException;
	
	/**
	 * Returns true if and only if current state of Storage successfully reverts
	 * to a previous state.
	 * @return true if undo is successful, false otherwise
	 */
	public boolean undo();
	
	/**
	 * Returns true if and only if current state of Storage successfully advances
	 * to a next state.
	 * @return true if redo is successful, false otherwise
	 */
	public boolean redo();
	
	/**
	 * Returns stateChange message which indicates the operation performed that 
	 * modified the state of Storage. Call before undo and after redo. stateChange
	 * message is invalid if undo/redo returns false.
	 * @return
	 */
	public String getStateChange();
	
}
